//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

use clap::{Parser, Subcommand};
use std::process::exit;
use std::{
    io::{stderr, Write},
    path::PathBuf,
};

mod cmd_analyse;
mod cmd_commit_graph;
mod cmd_get_change;
mod cmd_head;
mod cmd_info;
mod cmd_list_branch;
mod cmd_list_commit;
mod cmd_list_config;
mod cmd_list_remote;
mod cmd_list_stash;
mod cmd_list_tag;
mod cmd_set_config;
mod cmd_remove_config;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
    #[arg(long, value_name = "GIT_DIR")]
    git_path: PathBuf,

    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    ListTag,
    ListBranch {
        #[arg(long, default_value = "false")]
        remote: bool,
    },
    ListCommit {
        ref_name: String,
    },
    ListStash,
    GetChange {
        commit_id: String,
    },
    Analyse {
        branch: String,
        from_time: i64,
        to_time: i64,
    },
    ListRemote,
    Info,
    CommitGraph {
        commit_id: String,
    },
    ListConfig {
        #[arg(long, default_value = "false")]
        local: bool,
    },
    SetConfig {
        #[arg(long, default_value = "false")]
        local: bool,
        name: String,
        value: String,
    },
    RemoveConfig {
        #[arg(long, default_value = "false")]
        local: bool,
        name: String,
    },
    Head,
}

fn main() -> ! {
    let cli = Cli::parse();
    let result = match &cli.command {
        Commands::ListTag => cmd_list_tag::exec(cli.git_path),
        Commands::ListBranch { remote } => cmd_list_branch::exec(cli.git_path, remote),
        Commands::ListCommit { ref_name } => cmd_list_commit::exec(cli.git_path, ref_name),
        Commands::ListStash => cmd_list_stash::exec(cli.git_path),
        Commands::GetChange { commit_id } => cmd_get_change::exec(cli.git_path, commit_id),
        Commands::Analyse {
            branch,
            from_time,
            to_time,
        } => cmd_analyse::exec(cli.git_path, branch, from_time, to_time),
        Commands::ListRemote => cmd_list_remote::exec(cli.git_path),
        Commands::Info => cmd_info::exec(cli.git_path),
        Commands::CommitGraph { commit_id } => cmd_commit_graph::exec(cli.git_path, commit_id),
        Commands::ListConfig { local } => cmd_list_config::exec(cli.git_path, local),
        Commands::SetConfig { local, name, value } => {
            cmd_set_config::exec(cli.git_path, local, name, value)
        }
        Commands::RemoveConfig { local, name } => {
            cmd_remove_config::exec(cli.git_path, local, name)
        }
        Commands::Head => cmd_head::exec(cli.git_path),
    };
    if result.is_err() {
        let mut handle = stderr().lock();
        handle
            .write_all(format!("{}", result.err().unwrap().to_string()).as_bytes())
            .unwrap();
        exit(1);
    }
    exit(0);
}
